#ifndef CONFIGURATION_H
#define CONFIGURATION_H

#include <iostream>
#include "vector"

#include "ngl/Camera.h"
#include "ngl/SpotLight.h"

#include "ShaderObject.h"
#include "StaticObject.h"


/// @file Configuration.h
/// @brief parses xml config file
/// @author Perseedoss Rajiv
/// @version 1.0
/// @date 28.03.11
/// Revision History :
/// Initial Version 28.03.11
/// @class Configuration
/// @brief static class that deals with reading of xml configuration file and initialisations

class Configuration
{
public:
    /// @brief debug parameter used in all the files to enable debugging and console output
    static bool s_debug;

public :
    /// @brief set global parameters from the config file
    /// @param[out] o_frameRate the frame rate for the simulation
    /// @param[out] o_mouseMoveSensitivity sensitivity value of the mouse (x,y) movement
    static void initialiseWindow
                            (
                                int &o_frameRate,
                                int &o_mouseMoveSensitivity
                            );

    /// @brief create and return a camera from config file parameters
    /// @param[in] _aspect the aspect ratio to be used for the camera creation
    static ngl::Camera initialiseCamera(const float _aspect);

    /// @brief create and return a light source from config file parameters
    static ngl::Light initialiseLight();

    /// @brief create and return the list of shaders from config file parameters
    static std::vector<ShaderObject*>* initialiseShader();

    /// @brief create and return the list of obstacles from config file parameters
    static std::vector<StaticObject*>* initialiseObstacles();

    /// @brief set the global parameters of the flock from config file
    /// @param[out] o_initialNumberOfBoids initial number of boids to create
    /// @param[out] o_normaliseRules flag to determine if velocity are to be normalised
    /// @param[out] o_cohesionEnabled flag to determine if cohesion is enabled
    /// @param[out] o_separationEnabled flag to determine if separation is enabled
    /// @param[out] o_alignmentEnabled flag to determine if alignment is enabled
    /// @param[out] o_cohesionWeight the weight of cohesion
    /// @param[out] o_separationWeight the weight of separation
    /// @param[out] o_alignmentWeight the weight of alignment
    /// @param[out] o_separationThreshold the minimum distance of separation between boids
    /// @param[out] o_neighbouringThreshold the minimum distance for neighbour formation between boids
    /// @param[out] o_enableFOVNeighbouring flag to determine whwther the fov neighbouring policy is enabled
    /// @param[out] o_neighbouringFOVAngle the field of view neighbouring angle
    /// @param[out] o_boidModel the model to be used to draw the boid
    /// @param[out] o_tendTowardPosition the global position to tend towards to
    /// @param[out] o_tendTowardWeight the weight of tend towards rule
    /// @param[out] o_externalForce the external force to be applied to the flock
    /// @param[out] o_externalForceWeight the weight of the external force rule
    /// @param[out] o_enableTendToward flag to determine if tend toward rule is enabled
    /// @param[out] o_enableExternalForce flag to determine if an external force is to be applied
    /// @param[out] o_enableObstacleAvoidance flag to determine if obstacle avoidance is enabled
    /// @param[out] o_obstacleAvoidanceWeight the weight of the obstacle avoidance rule
    /// @param[out] o_minSpeed the minimum speed of the flock
    /// @param[out] o_maxSpeed the maximum speed of the flock
    static void initialiseFlock
            (
                int &o_initialNumberOfBoids,
                bool &o_normaliseRules,
                bool &o_cohesionEnabled,
                bool &o_separationEnabled,
                bool &o_alignmentEnabled,
                float &o_cohesionWeight,
                float &o_separationWeight,
                float &o_alignmentWeight,
                float &o_separationThreshold,
                float &o_neighbouringThreshold,
                bool &o_enableFOVNeighbouring,
                float &o_neighbouringFOVAngle,
                std::string &o_boidModel,
                ngl::Vector &o_tendTowardPosition,
                float &o_tendTowardWeight,
                ngl::Vector &o_externalForce,
                float &o_externalForceWeight,
                bool &o_enableTendToward,
                bool &o_enableExternalForce,
                bool &o_enableObstacleAvoidance,
                float &o_obstacleAvoidanceWeight,
                float &o_minSpeed,
                float &o_maxSpeed
            );


private:
    /// @brief the path of the configuration xml file
    static std::string s_settingsDoc;

private:
    /// @brief utility function to split a string into a vector of floats
    /// @param[in] _str the input string to be split
    /// @param[in] _d the count of split parts to be used as the size of the vector
    static std::vector<float> getFloatVectorFromString
                                            (
                                                const std::string _str,
                                                const int _d
                                            );


};

#endif // CONFIGURATION_H
